package com.demo2do.fms.admin.web.controller.business;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.page.Page;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.fms.admin.entity.report.ExportType;
import com.demo2do.fms.admin.entity.report.business.ConsignorShipmentReportSearch;
import com.demo2do.fms.admin.entity.report.business.OutShipmentReportSearch;
import com.demo2do.fms.admin.entity.search.business.ConsignorShipmentSearch;
import com.demo2do.fms.admin.entity.search.business.OutShipmentSearch;
import com.demo2do.fms.admin.entity.security.Login;
import com.demo2do.fms.admin.service.business.OutShipmentService;
import com.demo2do.fms.admin.utils.FormatUtils;
import com.demo2do.fms.admin.visitor.impl.PersistentVisitor;
import com.demo2do.fms.admin.web.resolver.Secure;
import com.demo2do.fms.admin.web.view.ExcelTemplateView;
import com.demo2do.fms.entity.business.shipment.ShipmentLine;

/**
 * 外包指令、委托方销单
 * 
 * @author Ysy
 *
 */
@Controller
@RequestMapping("/out-shipments")
@MenuSetting("menu-business")
public class OutShipmentController {
    
    private static final Logger logger = LoggerFactory.getLogger(OutShipmentController.class);

    @Autowired
    private OutShipmentService outShipmentService;
    
    @Autowired
    private PersistentVisitor persistentVisitor;
    
    /**
     * 
     * target
     * 
     *  - search: 外包指令查询
     *  - dispatch: 外包指令派车查询
     *  - maintain: 外包指令维护查询
     * 
     * @param login
     * @param target
     * @return
     */
    @MenuSetting("submenu-out-shipment-{target}")
    @RequestMapping(value = "search", method = RequestMethod.GET, params = "target")
    public ModelAndView search(@Secure Login login,
                               @RequestParam("target") String target){
        
        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-search");
        
        modelAndView.addObject("region", login.isRegionUser());
        modelAndView.addObject("orgIds", login.getCurrOrgIds());
        
        modelAndView.addObject("target", target);
        
        return modelAndView;
        
    }
    
    /**
     * target
     * 
     *  - search: 外包指令查询
     *  - dispatch: 外包指令派车查询
     *  - maintain: 外包指令维护查询
     * 
     * @param outShipmentSearch
     * @param page
     * @param target
     * @param request
     * @return
     */
    @MenuSetting("submenu-out-shipment-{target}")
    @RequestMapping(value = "", method = RequestMethod.GET, params = {"filter", "target"})
    public ModelAndView onSearch(HttpServletRequest request,
                                 OutShipmentSearch outShipmentSearch,
                                 @RequestParam("target") String target,
                                 Page page){
        
        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-" + target + "-list");
        
        int totals = outShipmentService.count(outShipmentSearch);
        if(totals > 0) {
            
            List<ShipmentLine> shipments = outShipmentService.search(outShipmentSearch, page.with(totals));
        
            modelAndView.addObject("shipments", shipments);
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
        
        }
        
        modelAndView.addObject("totals", totals);
        modelAndView.addObject("target", target);
        
        return modelAndView;
    }
    
    /**
     * 生成派车单-提示页
     * 
     * @return
     */
    @RequestMapping(value = "/dispatch", method = RequestMethod.GET)
    public ModelAndView dispatch() {
        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-dispatch-confirm");
        return modelAndView;
    }
    
    /**
     * 生成派车单
     * 
     * @param name
     * @param loadNumbers
     * @return
     */
    @MenuSetting("submenu-out-shipment-dispatch")
    @RequestMapping(value = "/dispatch", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onDispatchingConfirm(@Secure(property = "name") String name,
                                                         @RequestParam("loadNumbers") List<String> loadNumbers) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            outShipmentService.generate(loadNumbers, name);
            
            httpResult.success().message("外包指令派车成功");
            
        } catch (Exception e) {
            httpResult.fail("500").message("外包指令派车失败");
            logger.error("#onDispatchingConfirm() - dispatch fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 取消派车-提示页
     * 
     * @return
     */
    @RequestMapping(value = "/cancel", method = RequestMethod.GET)
    public ModelAndView maintainingCancel() {
        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-maintain-cancel");
        return modelAndView;
    }
    
    /**
     * 取消派车
     * 
     * @param name
     * @param loadNumbers
     * @return
     */
    @MenuSetting("submenu-out-shipment-maintain")
    @RequestMapping(value = "/cancel", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onMaintainingCancel(@Secure(property = "name") String name,
                                                        @RequestParam("loadNumbers") List<String> loadNumbers) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            outShipmentService.cancel(loadNumbers, name);
            
            httpResult.success().message("取消外包指令派车成功");
            
        } catch (Exception e) {
            httpResult.fail("500").message("取消外包指令派车失败");
            logger.error("#onDispatchingConfirm() - cancel dispatch fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 委托方销单 - search panel
     * 
     * @param login
     * @return
     */
    @RequestMapping(value = "/dispose-search", method = RequestMethod.GET)
    @MenuSetting("submenu-balance-disposing")
    public ModelAndView searchConsignorShipment(@Secure Login login){

        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-dispose-search");
        
        modelAndView.addObject("region", login.isRegionUser());
        modelAndView.addObject("orgIds", login.getCurrOrgIds());
        
        return modelAndView;
    }
    
    /**
     * 委托方销单 - on search
     * 
     * @param consigorShipmentSearch
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params= "dispose")
    @MenuSetting("submenu-balance-disposing")
    public ModelAndView onSearchConsignorShipment(ConsignorShipmentSearch consigorShipmentSearch, 
                                                  Page page, HttpServletRequest request){

        ModelAndView modelAndView = new ModelAndView("business/out-shipment/out-shipment-dispose-list");
        
        int totals = outShipmentService.countConsignorOrder(consigorShipmentSearch);
        if(totals > 0){
            
            List<Map<String, Object>> results = outShipmentService.listConsignorOrder(consigorShipmentSearch, page.with(totals));
            modelAndView.addObject("results", results);
            
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        }
        
        return modelAndView;
        
    }
    
    /**
     * 委托方销单 - 销单
     * 
     * @param operator
     * @param financeIds
     * @return
     */
    @RequestMapping(value = "/dispose", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onDispose(@Secure(property = "name") String operator, 
                                              @RequestParam(name = "financeIds") List<Long> financeIds){
        
        HttpResult httpResult = new HttpResult();
        
        try{
            
            logger.warn("#onDispose() - dispose order, size=[{}]", financeIds.size());
            
            outShipmentService.dispose(financeIds, operator);
            
            httpResult.success().message("销单成功");
            
        } catch (Exception e) {
            httpResult.fail("500").message("销单失败！" + e.getMessage());
            logger.error("#onDispose() - dispose order fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 输出当前记录(外包调度指令)
     * 
     * @param search
     * @param target
     * @param page
     * @return
     */
    @RequestMapping(value = "/export-shipment", method = RequestMethod.GET)
    public ModelAndView export(OutShipmentSearch search, @RequestParam("target") String target, Page page) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("business/out-shipment-" + target + "-export.xlsx"));
        
        // 1. list shipment 
        int totals = outShipmentService.count(search);
        if(totals > 0) {
            List<ShipmentLine> shipments = outShipmentService.search(search, page.with(totals));
            modelAndView.addObject("shipments", shipments);
        }
        
        // 2. attribute
        modelAndView.addObject("type", ExportType.CURRENT);
        modelAndView.addObject("persist", persistentVisitor);
        
        // 3. format util
        FormatUtils fmt = new FormatUtils();
        modelAndView.addObject("fmt", fmt);
        
        return modelAndView;
        
    }
    
    /**
     * 输出所有记录(外包调度指令)
     * 
     * @param search
     * @param target
     * @return
     */
    @RequestMapping(value = "/export-all-shipment", method = RequestMethod.GET)
    public ModelAndView exportAll(OutShipmentReportSearch search, @RequestParam("target") String target) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("business/out-shipment-" + target + "-export.xlsx"));
        
        // 1. list result
        List<Map<String, Object>> results = outShipmentService.exportAll(search, search.buildRowMapper());
        modelAndView.addObject("results", results);
        
        // 2. attribute
        modelAndView.addObject("type", ExportType.ALL);
        
        // 3. format util
        FormatUtils fmt = new FormatUtils();
        modelAndView.addObject("fmt", fmt);
        
        logger.warn("#exportAll() - export size=[{}]...", results.size());
        
        return modelAndView;
        
    }
    
    /**
     * 输出当前记录/输出所有记录(委托方销单)
     * 
     * @param search
     * @param page
     * @return
     */
    @RequestMapping(value = "/export-dispose", method = RequestMethod.GET)
    public ModelAndView export(ConsignorShipmentReportSearch search, Page page) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("business/out-shipment-dispose-export.xlsx"));
        
        // 1. list result
        List<Map<String, Object>> results = outShipmentService.search(search, page);
        modelAndView.addObject("results", results);
        
        // 2. format util
        FormatUtils fmt = new FormatUtils();
        modelAndView.addObject("fmt", fmt);
        
        logger.warn("#exportAll() - export size=[{}]...", results.size());
        
        return modelAndView;
        
    }
    
}